﻿using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Web;
using IapApp;
using IapApp.Util.Logger;
using Image = System.Drawing.Image;

namespace IapService.Service
{
    public class FileService : Service
    {
        private static readonly string DirectoryPath;

        static FileService()
        {
            DirectoryPath = HttpContext.Current.Server.MapPath(AppGlobal.SaveFolderNameServerPath);
        }

        public static string Save()
        {
            var file = HttpContext.Current.Request.Files[0];
            var savePath = CheckAndCreateDirectory(DirectoryPath);

            return SaveUploadedImageToServer(savePath, file);
        }

        private static string CheckAndCreateDirectory(string directory)
        {
            if (!Directory.Exists(directory))
                Directory.CreateDirectory(directory);
            return directory;
        }

        private static ImageFormat GetImageType(string fileExt)
        {
            switch (fileExt)
            {
                case ".jpg":
                    return ImageFormat.Jpeg;
                case ".gif":
                    return ImageFormat.Gif;
                default: // (png)
                    return ImageFormat.Png;
            }
        }

        private static string SaveUploadedImageToServer(String filePath, HttpPostedFile file)
        {
            var mediaId = Guid.NewGuid();
            var fileNameExtension = Path.GetExtension(file.FileName).ToLower();

            var uploadedImage = Image.FromStream(file.InputStream);

            var fileName = mediaId + fileNameExtension;
            var fullSavePath = filePath + "\\" + fileName;
            var imageType = GetImageType(fileNameExtension);

            Log.Warn("FileService.SaveUploadedImageToServer[" + fullSavePath + "]");
            uploadedImage.Save(fullSavePath, imageType);
            uploadedImage.Dispose();
            
            return mediaId + fileNameExtension;
        }

        public static string GetContentType(string fileExtension)
        {
            string contentType;
            fileExtension = fileExtension.Replace(".", "");
            switch (fileExtension)
            {
                case "pdf": contentType = "application/pdf"; break;
                case "swf": contentType = "application/x-shockwave-flash"; break;

                case "gif": contentType = "image/gif"; break;
                case "jpeg": contentType = "image/jpg"; break;
                case "jpg": contentType = "image/jpg"; break;
                case "png": contentType = "image/png"; break;

                case "mp4": contentType = "video/mp4"; break;
                case "mpeg": contentType = "video/mpeg"; break;
                case "mov": contentType = "video/quicktime"; break;
                case "wmv":
                case "avi": contentType = "video/x-ms-wmv"; break;
                default: contentType = "application/octet-stream"; break;
            } 
            return contentType;
        }

        public static void GetImageByQuery()
        {
            if(HttpContext.Current.Request.QueryString.AllKeys.Any(s => s == "s"))
            {
                GetThumbnailByQuery();
            } else
            {
                GetFullImageByQuery();
            }
        }

        public static void GetFullImageByQuery()
        {
            var fileId = HttpContext.Current.Request.QueryString["id"];
            var filePath = DirectoryPath + "\\" + fileId;
            if (!File.Exists(filePath))
                return;

            var fileInfo = new FileInfo(filePath);

            HttpContext.Current.Response.Clear();
            HttpContext.Current.Response.ContentType = GetContentType(fileInfo.Extension);
            HttpContext.Current.Response.AddHeader("Content-Disposition", String.Format("inline;filename=\"{0}\"", fileInfo.Name));
            HttpContext.Current.Response.AddHeader("Content-Length", fileInfo.Length.ToString(CultureInfo.InvariantCulture));
            HttpContext.Current.Response.WriteFile(filePath);
            HttpContext.Current.Response.End();
        }

        private static void GetThumbnailByQuery()
        {
            var fileId = HttpContext.Current.Request.QueryString["id"];
            var thumbSize = int.Parse(HttpContext.Current.Request.QueryString["s"]);
            var filePath = DirectoryPath + "\\" + fileId;
            if (!File.Exists(filePath))
                return;

            var fileInfo = new FileInfo(filePath);
            Image thumbnailImage;
            using(var image = Image.FromFile(filePath))
            {
                thumbnailImage = image.GetThumbnailImage(thumbSize, thumbSize, () => true, IntPtr.Zero);
            }
            using (var imageStream = new MemoryStream())
            {
                thumbnailImage.Save(imageStream, ImageFormat.Png);
                var imageContent = new Byte[imageStream.Length];
                imageStream.Position = 0;
                imageStream.Read(imageContent, 0, (int)imageStream.Length);

                HttpContext.Current.Response.Clear();
                HttpContext.Current.Response.ContentType = GetContentType(fileInfo.Extension);
                HttpContext.Current.Response.BinaryWrite(imageContent);
                HttpContext.Current.Response.End();
            }
        }

        public static void Remove(Entity.Image item)
        {
            DeleteImagesInList(Directory.GetFiles(DirectoryPath, "*" + item.FileName + "*"));
        }

        private static void DeleteImagesInList(IEnumerable<string> imgList)
        {
            foreach (var img in imgList)
            {
                Log.Warn("FileService.DeleteImagesInList[" + img.ToString(CultureInfo.InvariantCulture) + "]");
                var imgInfo = new FileInfo(img);
                imgInfo.Delete();
            }
        }
    }
}